package com.qwert.shortlink.admin.common.biz.user;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import com.qwert.shortlink.admin.common.convention.exception.ClientException;
import com.qwert.shortlink.admin.common.enums.UserErrorCode;
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static com.qwert.shortlink.admin.common.constant.RedisCacheConstant.USER_LOGIN_KEY;


/**
 * 用户信息传输过滤器
 * @author qwert
 * @version 1.0.0
 * @create 2024/6/26 17:26
 **/
@RequiredArgsConstructor
public class UserTransmitFilter implements Filter {

    private final StringRedisTemplate stringRedisTemplate;
    private static final List<String> IGNORE_URL = Lists.newArrayList(
            "/api/shortlink/admin/v1/user/login",
            "/api/shortlink/admin/v1/user/has-username"
    );
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        String requestURI = httpServletRequest.getRequestURI();

        if(!IGNORE_URL.contains(requestURI)){
            String method = httpServletRequest.getMethod();
            if(!(Objects.equals(requestURI, "/api/shortlink/admin/v1/user") && Objects.equals("POST", method))){
                String username = httpServletRequest.getHeader("username");
                String token = httpServletRequest.getHeader("token");
                // 判空
                if(!StrUtil.isAllNotBlank(username, token)){
                    throw new ClientException(UserErrorCode.USER_TOKEN_FAIL);
                }
                String cacheToken = null;
                try {
                    cacheToken = stringRedisTemplate.opsForValue().get(USER_LOGIN_KEY + username);
                } catch (Exception e) {
                    throw new ClientException(UserErrorCode.USER_TOKEN_FAIL);
                }

                // 匹配token是否一致
                if (!Objects.equals(token, cacheToken)) {
                    throw new ClientException(UserErrorCode.USER_TOKEN_FAIL);
                }
                // 解析token
                Map<String, Object> claim = JwtUtil.parseToken(token);
                UserInfoDTO userInfoDTO = UserInfoDTO.builder()
                        .userId(claim.get("id").toString())
                        .username(claim.get("username").toString())
                        .build();
                UserContext.setUser(userInfoDTO);

            }
        }

        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            UserContext.removeUser();
        }
    }
}
